import logging

from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect

from formalchemy import FieldSet

from repoze.what.predicates import not_anonymous
from repoze.what.plugins.pylonshq import ActionProtector, ControllerProtector

from papyrus.lib.base import BaseController, render
from papyrus.model import meta, Article

log = logging.getLogger(__name__)

article_form = FieldSet(Article)
article_form.configure(
    options=[
        article_form.body.textarea("50x15"),
    ],
    exclude=[
        article_form.creation_date,
        article_form.labels,
        article_form.author,
        article_form.comments,
    ])


@ControllerProtector(not_anonymous())
class ArticlesController(BaseController):
    """REST Controller styled on the Atom Publishing Protocol"""
    # To properly map this controller, ensure your config/routing.py
    # file has a resource setup:
    #     map.resource('article', 'articles')

    def index(self, format='html'):
        """GET /articles: All items in the collection"""
        # url('articles')

        q = meta.Session.query(Article)
        q = q.order_by(Article.creation_date.desc())
        c.articles = q.all()

        return render("/admin/articles/list.mako")

    def create(self):
        """POST /articles: Create a new item"""
        # url('articles')

        article = Article()
        fs = article_form.bind(article, data=request.POST, session=meta.Session)
        if not fs.validate():
            c.fs = fs
            return render('/admin/articles/new.mako')
        fs.sync()
        article.author = request.environ["repoze.who.identity"]["user"]
        meta.Session.add(article)
        meta.Session.commit()
        return redirect(url('articles'))

    def new(self, format='html'):
        """GET /articles/new: Form to create a new item"""
        # url('new_article')

        c.fs = article_form.bind(session=meta.Session)
        return render('/admin/articles/new.mako')

    def update(self, id):
        """PUT /articles/id: Update an existing item"""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="PUT" />
        # Or using helpers:
        #    h.form(url('article', id=ID),
        #           method='put')
        # url('article', id=ID)

        article = meta.Session.query(Article).get(id)
        fs = article_form.bind(article, data=request.POST)
        if not fs.validate():
            c.fs = fs
            return render('/admin/articles/edit.mako')
        fs.sync()
        article.author = request.environ["repoze.who.identity"]["user"]
        meta.Session.add(article)
        meta.Session.commit()
        return redirect(url('articles'))

    def delete(self, id):
        """DELETE /articles/id: Delete an existing item"""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="DELETE" />
        # Or using helpers:
        #    h.form(url('article', id=ID),
        #           method='delete')
        # url('article', id=ID)
        article = meta.Session.query(Article).get(id)
        meta.Session.delete(article)
        meta.Session.commit()
        return redirect(url('articles'))

    def show(self, id, format='html'):
        """GET /articles/id: Show a specific item"""
        # url('article', id=ID)
        c.article = meta.Session.query(Article).get(id)
        return render('/blog/item.mako')

    def edit(self, id, format='html'):
        """GET /articles/id/edit: Form to edit an existing item"""
        # url('edit_article', id=ID)

        article = meta.Session.query(Article).get(id)
        c.fs = article_form.bind(article)
        return render('/admin/articles/edit.mako')
